#include <stdio.h>
#include <unistd.h>
#include <string.h>

#include "tcp.h"
#include "tunnel.h"
#include "share.h"
#include "fatal.h"
#include "config.h"

#define text printf

#define CHANNEL 2500


void help(void)
{
    text("Usage: ff [option]... [file/dir]...\n");
    text("      Fast file transfer\n");
    text("      + [file]...         share files\n");
    text("      . or [dir]          fetch files into dir\n");
    text("      ?                   show tunnel info\n");
}

int check_dir(const char *path)
{
    if (access(path, F_OK) == 0) {
        if (access(path, W_OK) == 0) {
            return 0;
        } else {
            text("no write permission: %s\n", path);
            return -1;
        }
    } else {
        text("not found dir: %s\n", path);
        return -1;
    }
}

int main(int argc, char *argv[])
{
    char ip[64] = {0};
    int port = 0;

    char buf[1024] = {0};
    int active = 0;

    if (argc == 1) {
        help();
        return 0;
    }

    if (argc == 2) {
        if (strcmp(argv[1], "+") == 0) {
            help();
            return -1;
        }

        if (strcmp(argv[1], "?") == 0) {
            get_conf(ip, &port);
            text("Tunnel Server: %s:%d\n", ip, port);
            return 0;
        }

        if (check_dir(argv[1]) != 0) {
            return -1;
        }
        active = TUNL_REQ_ACTIVE_YES; // tunnel sender, ff fetch
        if (chdir(argv[1]) != 0) {
            printf("can't get into dir: %s\n", argv[1]);
            return -1;
        }
    }

    if (argc > 2) {
        if (strcmp(argv[1], "+") != 0) {
            help();
            return -1;
        }
        active = TUNL_REQ_ACTIVE_NO; // tunnel recver, ff share
    }

    get_conf(ip, &port);

    tcp_t cli = {
        .addr = ip,
        .port = port,
    };

    if (tcp_new_cli(&cli) < 0) {
        printf("create tcp client failed!\n");
        return -1;
    }

    tunl_t tunl = {
        .active = active,
        .number  = CHANNEL,
    };

    if (tunl_set_req(buf, &tunl) < 0) {
        printf("tunnel set request failed\n");
        return -1;
    }

    int len = sendall(cli.sock, (uint8_t *)buf, strlen(buf));
    if (len <= 0) {
        printf("send request failed\n");
        return -1;
    }

    if (tunl.active == TUNL_REQ_ACTIVE_YES) { // download client
        len = recvbuf(cli.sock, (uint8_t *)buf, sizeof(buf));
        if (len <= 0) {
            printf("tcp recv failed\n");
            return -1;
        }
        if (tunl_get_res(buf, len, &tunl) < 0) {
            printf("parser response failed\n");
            return -2;
        }
    }

    share_init(0);
    if (tunl.active == TUNL_REQ_ACTIVE_YES) {
        download(cli.sock);
    } else {
        share(cli.sock, argv + 2, argc - 2);
    }

    return 0;
}
